class Direction:
    def __init__(self, start, small, big):
        self.lines = [[j*big+start+small*i for i in range(4)] for j in range(4)]
    def move(self, matrix):
        success = False
        for line in self.lines:
            if matrix[line[3]] == 0:
                ''' XXX0 '''
                if matrix[line[2]] == 0:
                    ''' XX00 '''
                    if matrix[line[1]] == 0:
                        ''' X000 '''
                        if matrix[line[0]] > 0:
                            ''' 2000 '''
                            success = True
                            matrix[line[3]] = matrix[line[0]]
                            matrix[line[0]] = 0                            
                    else:
                        ''' X200 '''
                        success = True
                        if matrix[line[0]] == matrix[line[1]]:
                            ''' 2200 '''
                            matrix[line[3]] = matrix[line[1]] * 2
                            matrix[line[0]] = 0
                        else:
                            ''' 0200 or 4200 '''
                            matrix[line[3]] = matrix[line[1]]
                            if matrix[line[0]] != 0:
                                ''' 4200 '''
                                matrix[line[2]] = matrix[line[0]]
                                matrix[line[0]] = 0
                        matrix[line[1]] = 0
                else:
                    ''' XX20 '''
                    success = True
                    if matrix[line[1]] == matrix[line[2]]:
                        ''' X220 '''
                        matrix[line[3]] = matrix[line[1]] * 2
                        matrix[line[1]] = 0
                        matrix[line[2]] = matrix[line[0]]
                        matrix[line[0]] = 0                        
                    else:
                        ''' X020 or X420 '''
                        matrix[line[3]] = matrix[line[2]]
                        if matrix[line[1]] == 0:
                            ''' X020 '''
                            if matrix[line[0]] == matrix[line[2]]:
                                ''' 2020 '''
                                matrix[line[1]] = matrix[line[2]] * 2                                
                                matrix[line[2]] = 0
                            else:
                                ''' 0020 or 4020 '''
                                matrix[line[2]] = matrix[line[0]]
                            matrix[line[0]] = 0
                        else:
                            ''' X420 '''
                            if matrix[line[1]] == matrix[line[0]]:
                                ''' 4420 '''
                                matrix[line[2]] = matrix[line[0]] * 2
                                matrix[line[0]] = 0
                            else:
                                ''' 8420 or 0420 '''
                                matrix[line[2]] = matrix[line[1]]
                                matrix[line[1]] = matrix[line[0]]
                                matrix[line[0]] = 0
            else:
                ''' XXX2 '''
                if matrix[line[2]] == 0:
                    ''' XX02 '''
                    if matrix[line[1]] == 0:
                        ''' X002 '''
                        if matrix[line[0]] == matrix[line[3]]:
                            ''' 2002 '''
                            matrix[line[3]] *= 2
                            matrix[line[0]] = 0
                            success = True
                        else:
                            ''' 0002 or 4002 '''
                            if matrix[line[0]] > 0:
                                ''' 4002 '''
                                matrix[line[2]] = matrix[line[0]]
                                matrix[line[0]] = 0
                                success = True
                    else:
                        ''' X202 or X402 '''
                        success = True
                        if matrix[line[1]] == matrix[line[3]]:
                            ''' X202 '''
                            matrix[line[3]] *= 2
                            matrix[line[2]] = matrix[line[0]]
                            matrix[line[1]] = 0
                        else:
                            ''' X402 '''
                            if matrix[line[1]] == matrix[line[0]]:
                                ''' 4402 '''
                                matrix[line[2]] = matrix[line[0]] * 2
                                matrix[line[1]] = 0
                            else:
                                ''' 0402 or 2402 '''
                                matrix[line[2]] = matrix[line[1]]
                                matrix[line[1]] = matrix[line[0]]
                        matrix[line[0]] = 0
                else:
                    ''' XX22 or XX42 '''
                    if matrix[line[2]] == matrix[line[3]]:
                        ''' XX22 '''
                        success = True
                        matrix[line[3]] *= 2
                        matrix[line[2]] = matrix[line[1]]
                        if matrix[line[0]] == matrix[line[1]]:
                            ''' 2222 or 0022 '''
                            matrix[line[2]] = matrix[line[1]] * 2
                            matrix[line[1]] = 0                            
                        else:
                            if matrix[line[1]] == 0:
                                ''' 2022 '''
                                matrix[line[2]] = matrix[line[0]]
                            else:
                                ''' 0222 or 4222 '''
                                matrix[line[1]] = matrix[line[0]]
                        matrix[line[0]] = 0
                    else:
                        ''' XX02 or XX42 '''
                        if matrix[line[2]] == 0:
                            ''' XX02 '''
                            if matrix[line[1]] == 0:
                                ''' X002 '''
                                if matrix[line[0]] > 0:
                                    ''' 2002 or 4002 '''
                                    success = True
                                    if matrix[line[0]] == matrix[line[3]]:
                                        ''' 2002 '''
                                        matrix[line[3]] *= 2
                                    else:
                                        ''' 4002 '''
                                        matrix[line[2]] = matrix[line[0]]
                                    matrix[line[0]] = 0                                    
                            else:
                                ''' X202 or X402 '''
                                success = True
                                if matrix[line[1]] == matrix[line[3]]:
                                    ''' X202 '''
                                    matrix[line[3]] *= 2
                                    matrix[line[2]] = matrix[line[0]]
                                    matrix[line[1]] = 0
                                else:
                                    ''' X402 '''
                                    matrix[line[2]] = matrix[line[1]]                                    
                                    if matrix[line[0]] == matrix[line[1]]:
                                        ''' 4402 '''
                                        matrix[line[2]] *= 2
                                        matrix[line[1]] = 0
                                    else:
                                        ''' 0402 or 2402 '''
                                        matrix[line[1]] = matrix[line[0]]
                                    matrix[line[0]] = 0
                        else:
                            ''' XX42 '''
                            if matrix[line[2]] == matrix[line[1]]:
                                ''' X442 '''
                                matrix[line[2]] *= 2
                                matrix[line[1]] = matrix[line[0]]
                                matrix[line[0]] = 0
                                success = True
                            else:
                                ''' X042 or X242 '''
                                if matrix[line[1]] == 0:
                                    ''' X042 '''
                                    if matrix[line[2]] == matrix[line[0]]:
                                        ''' 4042 '''
                                        matrix[line[2]] *= 2
                                        matrix[line[0]] = 0
                                        success = True
                                    else:
                                        ''' 0042 or 2042 '''
                                        if matrix[line[0]] > 0:
                                            ''' 2042 '''
                                            matrix[line[1]] = matrix[line[0]]
                                            matrix[line[0]] = 0
                                            success = True
                                else:
                                    ''' X242 '''
                                    if matrix[line[0]] == matrix[line[1]]:
                                        matrix[line[1]] *= 2
                                        matrix[line[0]] = 0
                                        success = True
                                        
def output(m):
    w = len(str(max(m))) 
    for i in range(4):
        print ('+' + '-' * (w +1)) * 4 + '+'
        for j in range(4):
            print '|{0:>{1}}'.format(m[i*4+j], w) ,
        print '|'
    print ('+' + '-' * (w +1)) * 4 + '+'

import random
m0 = [ x if x > 1 else 0 for x in [2**random.randint(0, 4) for i in range(16)]]

up = Direction(12, -4, 1)
down = Direction(0, 4, 1)
left = Direction(3, -1, 4)
right = Direction(0, 1, 4)


print '-------UP-------'
m = [x for x in m0]
output(m)
up.move(m)
output(m)
print ''

print '-------DOWN-------'
m = [x for x in m0]
output(m)
down.move(m)
output(m)
print ''

print '-------LEFT-------'
m = [x for x in m0]
output(m)
left.move(m)
output(m)
print ''

print '-------RIGHT-------'
m = [x for x in m0]
output(m)
right.move(m)
output(m)



